﻿using System;
using System.Xml;
using BasecampRestAPI;
using NUnit.Framework;
using TestBasecampRestAPI.Fakes;
using TestBasecampRestAPI.TestMoveToDoList;

namespace TestBasecampRestAPI
{
	[TestFixture]
	public class TestToDoList
	{
		FakeBaseCamp _camp;
		FakeRestWebService _service;
		IToDoList _list;

		[SetUp]
		public void SetUp()
		{
			_camp = FakeBaseCamp.GetInstance();
			_service = FakeRestWebService.GetInstance();
			_camp.ServiceGetFakeResult = _service;
			_list = ToDoList.GetInstance(_camp, GetNodeForXml(Properties.Resources.EmptyToDoList));
		}


		[Test]
		public void Construct()
		{
			Assert.IsNotNull(_list);
			Assert.AreEqual(8256, _list.Id);
			Assert.AreEqual("Xenobarbs", _list.Name);
			Assert.AreEqual("Putting the barbs on the xenos.", _list.Description);
			Assert.AreEqual(14, _list.Position);
			Assert.AreEqual(true, _list.Private);
			Assert.AreEqual(true, _list.Tracked);
		}

		[Test]
		public void Project()
		{
			FakeProject project = new FakeProject
			{
				Id = 6969,
				Name = "FakeProject",
				CreatedOn = new DateTime(1969, 12, 3, 16, 45, 45),
				Status = "open",
				LastChangedOn = new DateTime(1977, 12, 3, 16, 45, 45),
				Announcement = "Flag day for all users",
				StartPage = "1",
				ShowWriteBoards = true,
				ShowAnnouncement = true
			};
			_camp.GetProjectByIdFakeResult = project;
			IProject result = _list.Project;
			Assert.IsNotNull(result);
			Assert.IsTrue(_camp.GetProjectByIdCalled);
			Assert.AreEqual(6969, _camp.GetProjectByIdLastId);
			Assert.AreEqual(project, result);
		}

		[Test]
		public void Milestone()
		{
			FakeProject project = new FakeProject
			{
				Id = 6969,
				Name = "FakeProject",
				CreatedOn = new DateTime(1969, 12, 3, 16, 45, 45),
				Status = "open",
				LastChangedOn = new DateTime(1977, 12, 3, 16, 45, 45),
				Announcement = "Flag day for all users",
				StartPage = "1",
				ShowWriteBoards = true,
				ShowAnnouncement = true
			};
			_camp.GetProjectByIdFakeResult = project;
			FakeMilestone milestone = new FakeMilestone();
			project.GetMilestoneByIdFakeResult = milestone;
			IMilestone result = _list.Milestone;
			Assert.IsNotNull(result);
			Assert.IsTrue(project.GetMilestoneByIdCalled);
			Assert.AreEqual(1222, project.GetMilestoneByIdLastId);
			Assert.AreEqual(milestone, result);
		}

		[Test]
		public void CreateItem()
		{
			FakePerson responsibleParty = new FakePerson { Id = 22 };
			_service.GetRequestResponseElementFakeResult = TestBasecamp.GetElementForXml(Properties.Resources.FakeToDoItem);
			const string location = "/todo_items/1601.xml";
			_service.PostRequestGetLocationFakeResult = location;

			const string content = "This is the first ToDo item.";
			IToDoListItem item = _list.CreateItem(content, responsibleParty, true);

			Assert.AreEqual(content, item.Content);
			Assert.AreEqual(1601, item.Id);
			Assert.AreEqual(location, _service.GetRequestResponseElementLastRequestPath);
			Assert.AreEqual(HttpVerb.Get, _service.GetRequestResponseElementLastVerb);
		}

		[Test]
		public void Items()
		{
			_service.GetRequestResponseElementFakeResult = TestBasecamp.GetElementForXml(Properties.Resources.FakeToDoListItems);
			const string location = "/todo_lists/8256/todo_items.xml";
			IToDoListItem[] items = _list.Items;
			Assert.IsTrue(_service.GetRequestResponseElementCalled);
			Assert.AreEqual(location, _service.GetRequestResponseElementLastRequestPath);
			Assert.IsNotNull(items);
			Assert.AreEqual(5, items.Length);
		}

		[Test]
		public void Delete()
		{
			_list.Delete();
			Assert.IsTrue(_service.DeleteRequestCalled);
			Assert.AreEqual(ToDoList.PathForId(_list.Id), _service.DeleteRequestLastRequestPath);
		}

		[Test]
		public void PathForId()
		{
			Assert.AreEqual("todo_lists/1336.xml", ToDoList.PathForId(1336));
		}

		private static XmlNode GetNodeForXml(string xml)
		{
			return TestBasecamp.GetElementForXml(xml);
		}
	}
}
